import Jsrsasign from 'jsrsasign';
import CryptoJS from 'crypto-js';

// aes加密
export function aesEncrypt(data,secretKey,iv){
  let key = CryptoJS.enc.Utf8.parse(secretKey);
   let srcs = CryptoJS.enc.Utf8.parse(data);
   let encrypted = CryptoJS.AES.encrypt(srcs, key, { iv:CryptoJS.enc.Utf8.parse(iv),mode:CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
  //  return encrypted.toString();
  return CryptoJS.enc.Base64.stringify(encrypted.ciphertext)
}

//aes解密
export function aesDecrypt(data,secretKey,iv){
 const key = CryptoJS.enc.Utf8.parse(secretKey);
//  let srcs = CryptoJS.enc.Utf8.parse(data);
 let decrypt = CryptoJS.AES.decrypt(data, key, {iv:CryptoJS.enc.Utf8.parse(iv),mode:CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7});
 return decrypt.toString(CryptoJS.enc.Utf8);
}

//rsa加密
const rsaEncryption = (content,publicKey)=>{
  publicKey = "-----BEGIN PUBLIC KEY-----\n" +
  publicKey+
  "\n-----END PUBLIC KEY-----";
    const pub = Jsrsasign.KEYUTIL.getKey(publicKey);
    const enc = Jsrsasign. KJUR.crypto.Cipher.encrypt(content,pub);
    return Jsrsasign.hextob64(enc);
};


//rsa解密
const rsaDecrypt = (params,privateKey)=>{
    const prv = Jsrsasign.KEYUTIL.getKey(privateKey);
    const dec = Jsrsasign.KJUR.crypto.Cipher.decrypt(params,prv);
    console.log("jsrsasign decrypt: "+dec);
    return dec;
}

//签名
const rsaSign=(content,publicKey)=>{
   // 私钥
   let key = publicKey;
   publicKey = "-----BEGIN PRIVATE KEY-----\n" +
   key+
   "\n-----END PRIVATE KEY-----";
    // 创建 Signature 对象
    const signature =  new  Jsrsasign.KJUR.crypto.Signature({
        alg:'SHA1withRSA'
    })
    var pub = Jsrsasign.KEYUTIL.getKey(publicKey);
    signature.init(pub);
    signature.updateString(content)
    const signData = signature.sign();
    return Jsrsasign.hextob64(signData);
}

//验签
const verifSign=(content,privateKey,sign)=>{
    let signatureVf = Jsrsasign.KJUR.crypto.Signature({alg:HashMap,prvkeypem:privateKey});
    signatureVf.updateString(content);
    // !接受的参数是16进制字符串!
    return signatureVf.verify(Jsrsasign.b64tohex(sign));
}

//获取时间
const getDateTimeToString = () => {
    const date_ = new Date()
    let year = date_.getFullYear()
    let month = date_.getMonth() + 1
    let day = date_.getDate()
    if (month < 10){
      month = '0' + month
    } 
    if (day < 10){
      day = '0' + day
    } 
    let hours = date_.getHours()
    let mins = date_.getMinutes()
    let secs = date_.getSeconds()
    let msecs = date_.getMilliseconds()
    if (hours < 10){
      hours = '0' + hours
    } 
    if (mins < 10){
      mins = '0' + mins
    } 
    if (secs < 10){
      secs = '0' + secs
    }
    if (msecs < 10){
      secs = '0' + msecs
    } 
    return year + '' + month + '' + day + '' + hours + '' + mins + '' + secs
  }
  
  //获取随机数
  const getNonce = () => {
    return Math.random().toString(36).substring(2)
  }

   //获取16位随机数
   const get16Nonce = () => {
    return random(16)
  }

  const random=(length)=>{
    var str = Math.random().toString(36).substr(2);
    if (str.length>=length) {
        return str.substr(0, length);
    }
    str += random(length-str.length);
    return str;
}
  /**
 * 接口参数签名
 * @param {*} config 请求配置
 */
export const sign = (config, appId,key) => {
  // 获取到秒级的时间戳,与后端对应
  let salt = get16Nonce();
  let encryptkey = get16Nonce();
  let data = {
    APPID: appId,
    TIMESTAMP: getDateTimeToString(),
    NONCE: getNonce(),
    SIGN:'',
    salt: JSON.parse(JSON.stringify(salt)),
    encryptkey:JSON.parse(JSON.stringify(encryptkey))
  }
  let keys = [];
  let singData={};
  const _singKey = 'SIGN'
  const _secretKey = 'SECRETKEY'
  if (config.method === 'get') {
    // url参数签名
    singData['securityParam'] = config.params = config.params ? aesEncrypt(JSON.stringify(config.params),data.encryptkey,data.salt) : aesEncrypt(JSON.stringify({}),data.encryptkey,data.salt)
    keys = Object.keys(singData)
  } else {
    // request body参数的内容
    singData['securityParam'] = config.data = config.data ? aesEncrypt(JSON.stringify(config.data),data.encryptkey,data.salt) : aesEncrypt(JSON.stringify({}),data.encryptkey,data.salt)
    keys = Object.keys(singData)
  }
  // 排序
  const skeys = keys.sort()
  let str = ''
  skeys.filter(k => {
    return k !== _singKey && k !== _secretKey
  }).map(k => {
    const v = singData[k]
    if (v || v === 0) {
      // 参数值为空，则不参与签名
      str = str + k + '=' + v + '&'
    }
  })
  data[_singKey] = rsaSign(str,key.privateKey);
  data.salt = rsaEncryption(data.salt,key.publicKey);
  data.encryptkey = rsaEncryption(data.encryptkey,key.publicKey);
  return {header:data,reqData:singData,salt:salt,encryptkey:encryptkey};
};